import Chart, { ChartConfigMgr, CurrentActiveChart } from '../Charts/Charts';
import { EffectConfigMap, StateNode } from '../core/effect';
export const DataSourceLoadingMap = new Map<DataSource, boolean>();
export interface IDataSource {
    dataFn: (...args: any) => Promise<any>;
    mateDataFn: (...args: any) => Promise<any>;
}

const DataSourceChartMap = new WeakMap<DataSource, Chart<any>[]>();

export interface IDataSourceConfig {
    dataSourceURL: string;
    mateDataURL: string;
    defaultFilter?: any;
    defaultMateFilter?: any;
}
export interface IDimensionProps {
    dimensionProp: string,
    valueProps: Array<string>
}
const DataSourceStateMap = new WeakMap<DataSource, Array<StateNode<any>>>();

export class DataSourceMgr {
    private datasource: DataSource;
    // private mateData: any = {};
    // originData: any = {};
    get mateData() {
        return this.datasource.mateData;
    }
    get originData() {
        return this.datasource.originData;
    }
    getDataSource() {
        return this.datasource;
    }
    private configMgr: ChartConfigMgr<any>;
    useState<T>(param: T): StateNode<T> {
        const node = new StateNode<T>(param);
        const currentStates = DataSourceStateMap.get(this.datasource) || [];
        currentStates.push(node);
        DataSourceStateMap.set(this.datasource, currentStates);
        return node;
    }
    constructor(datasource: DataSource, confMgr: ChartConfigMgr<any>) {
        this.datasource = datasource;
        this.configMgr = confMgr;
        datasource.getDataFn((mateData, originData) => {
        });
    }
    getFilter() {
        return this.datasource.fileterParams;
    }
    setFilter(params: any) {
        this.datasource.setFilter(params);
        DataSourceLoadingMap.set(this.datasource, true);
    }
    /**
     * 只针对当前图表的数据源进行更新，与其他图表无关
     * @param activeDS
     */
    private setDataSource(activeDS: DataSource) {
        if (CurrentActiveChart) {
            /**
             * 1，从DataSourceChartMap中移除当前数据源与CurrentActiveChart的关联
             * 2，在新的DataSourceChartMap对象中，添加activeDS与CurrentActiveChart的关联
             * 3，强制刷新CurrentActiveChart
             */
            const currentDsCharts = DataSourceChartMap.get(this.datasource) || [];
            const targetIndex = currentDsCharts.findIndex(chart => chart == CurrentActiveChart);
            if (targetIndex >= 0) {
                currentDsCharts.splice(targetIndex, 1);  //将CurrentActiveChart从当前数据源对应中删除
            }
            DataSourceChartMap.set(this.datasource, currentDsCharts);
            const newDsCharts = DataSourceChartMap.get(activeDS) || [];
            //如果当前数据源中存在其他的图表，则将当前图表存入MAP结构，用于后续更新
            if (newDsCharts.indexOf(CurrentActiveChart) < 0) {
                newDsCharts.push(CurrentActiveChart);
            }
            DataSourceChartMap.set(activeDS, newDsCharts);
            this.datasource = activeDS;
            //连同元数据一起刷新掉
            activeDS.getAllDataConfigs().then(response => {
                this.originData = response;
                CurrentActiveChart?.renderCallBack();
            }).catch(ex => {
            })
        }
    }
}
export default class DataSource {
    private dataFn: (...args: any) => Promise<any>;
    private mateDataFn: (...args: any) => Promise<any>;
    fileterParams: any = {};
    //元数据
    mateData: any = {};
    loading: boolean = false;
    //后台接口返回的实时数据
    originData: any = {};
    constructor(dsInit: IDataSource) {
        this.dataFn = dsInit.dataFn;
        this.mateDataFn = dsInit.mateDataFn;
    }
    setFilter(filter: any) {
        this.fileterParams = filter;
        this.dataFn = this.dataFn.bind(null, filter);
        this.getDataFn();
    }
    getDataFn(callback?: (mateData: any, originData: any) => void) {
        this.loading = true;
        DataSourceLoadingMap.set(this, true);
        this.dataFn().then(response => {
            this.originData = response.data.data.datas;
            this.mateData = response.data.data.mateData;
            this.loading = false;
            DataSourceLoadingMap.set(this, false);
            callback && callback(this.mateData, this.originData);
        }).catch(ex => {
        })
    }
    getAllDataConfigs() {
        return Promise.all([this.dataFn(), this.mateDataFn()]);
    }
}



// export function  dataSourceCreater(dsInit:IDataSource){
//     return new DataSource(dsInit);
// }
